#!/usr/bin/env python
"""
:mod:`pynchon.bio.atom`
=======================

Provides support for 3D structures atoms, molecules and macromolecules.
"""

import numpy as np
from pynchon.core.entity import Entity, Entity_sequencer
from pynchon.core.point import Point3dFloat64, PointVector3dFloat64, \
                               PointArray3dFloat64

class Atom(Point3dFloat64):
    """
    Represents a point in 3d Cartesian coordinates.
    """
        

class AtomVector(PointVector3dFloat64, Atom):
    """
    Represents a vector of ``Atom`` entities. See: ``Atom``.
    """

  
class Model(AtomVector):
    """
    Represents a single structural model. Represents a vector of ``Atom`` 
    entities. See: ``Atom``.
    """


class AtomData(Entity):
    """
    An entity with a structured data type to store the non-coordinate fields in 
    a "ATOM" or "HETATM" PDB-line. See: ``pynchon.bio.io.pdb`` for details.
    """
    rank = 0
    data_type = [('at_type','S6'),
                 ('ser_num','int32'),
                 ('at_id','S4'),
                 ('alt_loc','S1'),
                 ('res_name','S3'),
                 ('chain_id','S1'),
                 ('res_id','int32'),
                 ('res_ic','S1'),
                 ('occupancy','float64'),
                 ('bfactor','float64'),
                 ('element','S2'),
                 ('charge','S2')]
    fval = ('      ',0,'    ',' ','   ',' ',0,' ',0.,0.,'  ','  ')
        
    @classmethod
    def raw_sequence(cls, rank, dtype, fval, metadata, fast, kwargs, entities):
        try:
            struct = np.array(entities, dtype=dtype)
        except ValueError:
            raise ValueError('Got invalid AtomData input.')
        return (struct,)

   
class ModelData(AtomData):
    """
    Represents a vector (rank-1 array) of ``AtomDatay`` entities. See: 
    ``AtomData``.
    """
    rank = 1
    
    @classmethod
    def raw_sequence(cls, rank, dtype, fval, metadata, fast, kwargs, entities):
        return Entity_sequencer(cls, dtype, fval, metadata, entities)

